#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#include "Spline.h"
#include <jsoncpp/json/json.h>
using namespace std;
#define spline BsplineInterpolation 

class Function1 : public Function
{
public:
    double operator()(double _x)
    {
        double f;
        f = 1.0 / (1.0 + 25.0 * _x * _x);
        return f;
    }
    double diff1(double _x) 
    {
        double f;
        f = -50.0 * _x / pow(1 + 25.0 * _x * _x, 2);
        return f;  
    }
    double diff2(double _x)
    {
        double f;
        f = 50.0 * (75.0 * _x * _x - 1) / pow(1.0 + 25.0 * _x * _x, 3);
        return f;  
    }
};

int main()
{
    Json::Reader reader;
    Json::Value root;
    ifstream in("questionA.json", ios::binary);
    vector<int> num;
    double left, right;
    int condition, ord;
    Function1 f;
    if (reader.parse(in, root))
	{
        left = root["left"].asDouble();
        right = root["right"].asDouble();
        for (int i = 0; i < root["N"].size(); i++){
            int n = root["N"][i].asInt();
            num.push_back(n);
        }
        condition = root["condition"].asInt();
        ord = root["order"].asInt();
    }
    for (int i = 0; i < num.size(); i++)
	{
        vector<double> v1;
        for (int j = 0; j < num[i]; j++)
		{
            v1.push_back(left + j * (right - left) / (num[i] - 1));
        }
        spline v2(f, v1, condition, ord);
        v2.solve();
        cout << "N = " << num[i] << endl;
        for (int j = 0; j < 200; j++)
		{
            cout << v2(left + j * 0.01) << ",";
        }
        cout << v2(right) << endl;
        double error = 0;
        for (int j = 0; j < num[i] - 1; j++)
		{
            if (fabs(v2(0.5 * (v1[j] + v1[j + 1])) - f(0.5 * (v1[j] + v1[j + 1]))) > error)
                error = fabs(v2(0.5 * (v1[j] + v1[j + 1])) - f(0.5 * (v1[j] + v1[j + 1])));
        }
        cout << "error = " << error << endl;
	}
    return 0;
}
